package wscom

import (
	"errors"
	"sync"
	"time"
	"dhfshop/utils/response"
	//"github.com/astaxie/beego"
)

const (
	pingPeriod = (10 * 9) / 10 //pongWait*9/10
)

/**
 * 连接池
 */
type connectHub struct {
	lock     *sync.RWMutex          //锁
	register chan *ConnectSvr       //注册连接
	msg      chan []byte            //广播消息
	cList    map[string]*ConnectSvr //所有连接客户端 token(1:1)连接句柄ws
}

var ConnectHub *connectHub

func NewConnectHub() *connectHub {
	return &connectHub{
		lock:     new(sync.RWMutex),
		register: make(chan *ConnectSvr),
		msg:      make(chan []byte),
		cList:    make(map[string]*ConnectSvr),
	}
}

func (hub *connectHub) Run() {
	ticker := time.NewTicker(pingPeriod * time.Second)
	defer func() {
		ticker.Stop()
	}()
	for {
		select {
		case c := <-hub.register:
			hub.add(c)
		case m := <-hub.msg:
			for _, c := range hub.cList {
				c.sendText(m)
			}
		case <-ticker.C:
			for _, c := range hub.cList {
				if c != nil {
					if err := c.ping(); err == nil {
						//beego.Debug("ping is correct")
						continue
					} else {
						token, _ := c.getToken()
						//beego.Debug("ping is error and close token", token)
						hub.close(token)
					}
				}
			}
			hub.statistics()
		}
	}
}

/**
 * 关闭连接
 */
func (hub *connectHub) close(token string) {
	hub.lock.RLock()
	defer hub.lock.RUnlock()
	if c, ok := hub.cList[token]; ok {
		c.discon()
		delete(hub.cList, token)
		//LoginSvr.Logout(token)
	}
}

/**
 * 添加句柄到连接池
 */
func (hub *connectHub) add(c *ConnectSvr) (err error) {
	hub.lock.RLock()
	defer hub.lock.RUnlock()
	if token, err := c.getToken(); err == nil {
		hub.cList[token] = c
	}
	return err
}

/**
 * 获得连接句柄
 * c/	u/
 */
func (hub *connectHub) GetConnectSvr(query string) (*ConnectSvr, error) {
	c, ok := hub.cList[query]
	if ok {
		if _, err := c.getToken(); err == nil {
			return c, err
		}
	}
	err := errors.New(response.LangConf.Get("3000").MustString())
	return &ConnectSvr{}, err
}

func (hub *connectHub) Broadcast(message []byte) {
	hub.msg <- message
}

/**
 * 连接统计
 */
func (hub *connectHub) statistics() {
	/*
	beego.Debug("Connections Number:", len(hub.cList))
	for key, _:= range hub.cList {
	   beego.Debug("Connections token:", key)
	}
	*/
}
